/*
 * 创建日期 2005-10-8
 *
 * 更改所生成文件模板为
 * 窗口 > 首选项 > Java > 代码生成 > 代码和注释
 */
package com.vanda.report.dp;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.validator.GenericValidator;

import com.vanda.report.ReportException;
import com.vanda.report.ReportInnerData;
import com.vanda.report.element.Element;
import com.vanda.util.LogFunc;

/**
 * 聚集函数父类 <br>
 * <p>
 * 
 * @author eagle <br>
 * @version Version 1.00 <br>
 */
public abstract class AggregationElement extends Element {
	/** 指定需处理的列名，例：如是求和，则指定需求和的列名 */
	private String field = null;
	/** 指定查询的列名，只能指定一个列名 */
	private String group_field = null;
	/** 指定查询列名的值，如有多个值，以","作为分隔符 */
	private String group_value = null;

	/**
	 * 标签执行方法，递归执行
	 * 临时变量说明:
	 * temp1:原始数据list
	 * temp2:当前行数
	 * temp3:保存每个gourp的起始结束位置,int[2]
	 * @param obj
	 */
	public void execute(Object obj) throws ReportException {
		ReportInnerData reportData = (ReportInnerData) obj;

		try {
			int[] pos = (int[]) reportData.getTemp4();
			//取上下文数据,是全部原始数据
			List contextObj = (List) reportData.getTemp1();
			//取得字段集
			String[] fields = field.split(",");
			for(int i=0;i<fields.length;i++){
				fields[i] = fields[i].trim();
			}

			//取得计算值
			Object[] handleValues = getHandleValue(contextObj,pos);
			
			contextObj = (List)handleValues[0];
			pos = (int[])handleValues[1];
			
			//聚集计算
			Object[] objs = aggregate(contextObj, pos[0], pos[1], fields);

			//如果有新增行,则插入聚集数据
			if (isCreateRecord() == true) {
				Object newRecord = reportData.getContextData();

				for (int i = 0; i < fields.length; i++) {
					super.setProperty(newRecord, fields[i], objs[i]);
				}
			}

			//super.execute(obj);
		} catch (ReportException e) {
			throw e;
		} catch (Exception e) {
			throw new ReportException(e);
		}

	}
	
	/**
	 * 返回待处理的值
	 * @param rowList
	 * @param pos
	 * @return
	 * @throws Exception
	 */
	private Object[] getHandleValue(List rowList,int[] pos) throws Exception{
		Object[] values = new Object[2];
		//如果没有待聚集的，则直接返回
		if(GenericValidator.isBlankOrNull(group_field) 
			|| GenericValidator.isBlankOrNull(group_value)){
			values[0] = rowList;
			values[1] = pos;
			return values;
		}
		String[] groupValues = group_value.split(",");
		Map map = new HashMap();
		for(int i=0;i<groupValues.length;i++){
			map.put(groupValues[i],"");
		}
		
		
		List resultList = new ArrayList();
		for(int i=0;i<rowList.size();i++){
			Object row = rowList.get(i);
			Object groupValue = super.getProperty(row,group_field);
			
			//如果有值，则设置到resultList
			if(map.get(groupValue.toString()) != null){
				resultList.add(row);
			}
		}
		
		values[0] = resultList;
		
		int[] resultPos = new int[2];
		resultPos[0] = 0;
		resultPos[1] = resultList.size();
		
		values[1] = resultPos;
		
		return values;
	}
	
	public static void main(String[] args){
		com.vanda.report.ReportGroupRow row
			= new com.vanda.report.ReportGroupRow();
		
		SumElement element = new SumElement();
		String name="a.name1";
		try{
			PropertyUtils.setNestedProperty(row, name, "eagle");
			
		}catch(Exception e){
			e.printStackTrace();
		}
		LogFunc.info("size = "+row.size());
		LogFunc.info("value = "+row.get(name));
	}

	/**
	 * 聚集计算
	 * @param beanList
	 * @return
	 */
	public abstract Object[] aggregate(
		List beanList,
		int start,
		int end,
		String[] property)
		throws ReportException;

	protected boolean isCreateRecord() {
		return true;
	}

	/**
	 * @return
	 */
	public String getField() {
		return field;
	}

	/**
	 * @param string
	 */
	public void setField(String string) {
		field = string;
	}
	/**
	 * @return
	 */
	public String getGroup_field() {
		return group_field;
	}

	/**
	 * @return
	 */
	public String getGroup_value() {
		return group_value;
	}

	/**
	 * @param string
	 */
	public void setGroup_field(String string) {
		group_field = string;
	}

	/**
	 * @param string
	 */
	public void setGroup_value(String string) {
		group_value = string;
	}

}
